#include <iostream>
#include <fstream>
#include <string.h>
#include <netdb.h>
#include <time.h>
#include "portscanner.h"
#include "services.h"

using namespace std;

void usage(char *name)
{
   printf("Usage: %s -p<first port>-<second port> [options]\n",name);
   printf("\n  * -s [ip address]  -  single scan\n  * -w [subnet]      -  whole scan\n  * -h [hostname]    -  single scan by hostname\n");
   printf("\nExample: %s -p1-1000 -s 192.168.0.1\n",name);
   exit(0);
}

int main(int argc, char **argv)
{
   if(argc != 4)
   {
      usage(argv[0]);
   }

   int port[2];
   float percent = 0;
   string addr[255];
   int a=0,b=0,c=0,d=0,e=0,h=0,p;

   if(argv[1][0] == '-' && argv[1][1] == 'p')
   {
      int first=2,count=2;
      char num[10];
      for(int i=2;i<strlen(argv[1])+1;i++)
      {
          if(argv[1][i] == '-' || argv[1][i] == '\0')
          {
              for(int j=first;j<i;j++)
              {
                 num[j-first] = argv[1][j];
                 num[j-first+1] = '\0';
              }
              if(first == 2)
              {
                 port[0] = atoi(num);
                 strcpy(num,"\0");
              }
              else
              {
                 port[1] = atoi(num);
              }
              first = i+1;
          }
      }
   }
   else
   {
      usage(argv[0]);
   }

   if(strcmp(argv[2],"-w") == 0)
   {
      char call[1024];
      strcpy(call,"./alive.sh ");
      strncat(call,argv[3],sizeof(call)-strlen(call)-1);
      system(call);
      fstream file("live.txt",ios::in);
      while(!file.eof())
      {
         getline(file,addr[b]);
         b++;
      }
   }
   else if(strcmp(argv[2],"-s") == 0)
   {
      strcpy((char*)addr[0].c_str(),argv[3]);
      b = 2;
   }
   else if(strcmp(argv[2],"-h") == 0)
   {
      const hostent* host_info = 0;
      host_info =  gethostbyname(argv[3]);
      const in_addr* address = (in_addr*)host_info->h_addr_list[0];
      strcpy((char*)addr[0].c_str(),inet_ntoa(*address));
      b = 2;
   }
   else
   {
      usage(argv[0]);
   }

   time_t begin = time(NULL);
   printf("Initiating scan\n\n");

   while(a < b-1)
   {
      printf("Scanning ports %d - %d on %s:\n",port[0],port[1],addr[a].c_str());

      boost::thread_group g;
      char progress[100];
      d = ((port[1]-port[0])+1) / 10;
      e = port[0];
      percent = 0;

      printf("[");

      for(int i=0;i<96;i++)
      {
         printf(" ");
      }
      printf("] - %%0");

      while(h < d)
      {
         g.create_thread(boost::bind(&scan, port[0]+h, addr[a].c_str()));
         for(int i=1;i<10;i++)
         {
             g.create_thread(boost::bind(&scan, e+h+d*i, addr[a].c_str()));
         }

         strcpy(progress,"[");
         printf("\r%s",progress);
         percent = (float)perc / (float)port[1];
         percent = (percent * 100);
         p = (int)percent;

         for(int i=0;i<p;i++)
         {
            strcat(progress,"=");
         }
         for(int i=0;i<96-p;i++)
         {
            strcat(progress," ");
         }
         strcat(progress,"]");

         printf("\r%s - %%%d",progress,(int)percent);

         g.join_all();

         h++;
      }

      g.create_thread(boost::bind(&scan, port[1], addr[a].c_str()));
      g.join_all();

      printf("\r%s - %%100\n\n",progress);
      printf("Open ports on %s: \n",addr[a].c_str());

      if(arraynum == 0)
      {
         printf("\tAll scanned ports are closed.\n");
      }

      while(c <= arraynum-1)
      {
         const char *service = servicefind(oports[c]);
         printf ("\t%d - %s\n",oports[c],service);
         c++;
      }

      printf("\n");
      memset((void*)&oports,0,sizeof(oports));
      arraynum = 0;
      a++;
      c = 0;
   }

   printf ("Scan Completed.\nTotal Time: %d seconds\n",time(NULL) - begin);
   return 0;
}
